/* eslint-disable cognitive-complexity/cognitive-complexity-forced */
import { Form } from 'antd';
import { cloneDeep, isNil } from 'lodash';
import React, { useCallback, useEffect, useState } from 'react';

import { LayerInfoFE } from '@/pages/TemplateEditor/interface';

import { LayerTypeBE, LayerTypeFE } from '../../../../../../../constant';
import { emitter, EVENT_TYPE } from '../../../../../../../events';
import { DeepPartial } from '../../../../../../../interface';
import BaseConfigs from './components/BaseConfigs';
import ColorConfigs from './components/ColorConfigs';
import ImageConfigs from './components/ImageConfigs';
import ProductImageConfigs from './components/ProductImageConfigs';
import ShapeConfigs from './components/ShapeConfigs';
import TextConfigs from './components/TextConfigs';
import { initialShapeDataByType } from './constant';
import {
  useHasColor,
  useHasCorner,
  useHasImage,
  useHasProductImage,
  useHasShapes,
  useHasText
} from './hooks';
import styles from './index.module.less';
import {
  handleImageValuesChange,
  handleProductImageValuesChange,
  hexToRgba
} from './utils';

interface Props {
  index: number;
  screenSize: string;
  layerData: LayerInfoFE;
  onChange: (
    data: DeepPartial<LayerInfoFE>,
    needUpdateForm?: boolean,
    needRerenderScreen?: boolean
  ) => void;
  onSetCropLayerId: (id: string) => void;
}

const LayerConfigs = ({
  index,
  layerData,
  screenSize,
  onChange,
  onSetCropLayerId
}: Props): JSX.Element => {
  const [canvasWidth, canvasHeight] = screenSize.split('x').map(Number);
  const [form] = Form.useForm();

  const beType = layerData.data.type;
  const hasImage = useHasImage(beType);
  const hasShapes = useHasShapes(beType);
  const hasProductImage = useHasProductImage(beType);
  const hasCorner = useHasCorner(beType, layerData.type);
  const { hasBorderColor, hasFillColor } = useHasColor(beType, layerData.type);
  const hasText = useHasText(beType);
  const [loading, setLoading] = useState(false);

  const handleValuesChange = useCallback(
    (values: DeepPartial<LayerInfoFE>): void => {
      let needUpdateForm = false;
      let needRerenderScreen = false;

      // position和size，为null则未输入，不进行处理
      ['left', 'top', 'width', 'height'].forEach((key) => {
        if (key in values && values[key] == null) {
          Reflect.deleteProperty(values, key);
        }
      });

      // product类型图片，修改长宽时需要锁定长宽比
      if (
        beType === LayerTypeBE.Product &&
        isNil(values.src) &&
        layerData.src
      ) {
        const ratio = layerData.width / layerData.height;
        if (values.width != null) {
          values.height = values.width / ratio;
        } else if (values.height != null) {
          values.width = values.height * ratio;
        }
      }

      // 如果修改了尺寸，则需要修改坐标，以保证界面上position不会变
      if (values.width != null) {
        values.left = layerData.left - layerData.width / 2 + values.width / 2;
        needUpdateForm = true;
      }

      if (values.height != null) {
        values.top = layerData.top - layerData.height / 2 + values.height / 2;
        needUpdateForm = true;
      }

      // 角度处理
      if (values.data?.rotation != null) {
        values.angle = values.data.rotation % 360;
      }

      // 边框颜色修改需要特殊处理
      if (values.data?.graphics) {
        const { fillColor, transparency, borderColor, borderOpacity } =
          values.data.graphics;

        if (fillColor || !isNil(transparency)) {
          values.fill = hexToRgba(
            fillColor || layerData.data.graphics.fillColor,
            !isNil(transparency)
              ? transparency
              : layerData.data.graphics.transparency
          );
        }

        if (borderColor || !isNil(borderOpacity)) {
          values.stroke = hexToRgba(
            borderColor || layerData.data.graphics.borderColor,
            !isNil(borderOpacity)
              ? borderOpacity
              : layerData.data.graphics.borderOpacity
          );
        }
      }

      // 切换shape type的重置处理
      if (values.type && values.type !== LayerTypeFE.Image) {
        const shapeInitialData = initialShapeDataByType[values.type];
        Object.assign(values, cloneDeep(shapeInitialData));
        needUpdateForm = true;
        needRerenderScreen = true;
      }

      // 如果当前切换了type，则需要使用最新的type
      const currentType = values.type || layerData.type;

      // Rect类型修改borderRadius，需要改为rx ry
      if (
        currentType === LayerTypeFE.Rect &&
        values.data?.graphics?.borderRadius != null
      ) {
        values.rx = values.data.graphics.borderRadius;
        values.ry = values.data.graphics.borderRadius;
      }

      // Rect和Triangular类型修改borderRadius，需要改为radius
      if (
        currentType === LayerTypeFE.Triangular &&
        values.data?.graphics?.borderRadius != null
      ) {
        values.radius = values.data.graphics.borderRadius;
      }

      // Ellipse类型修改width或height，需要改为rx ry
      if (
        currentType === LayerTypeFE.Ellipse &&
        (values.width || values.height)
      ) {
        values.rx = (values.width || layerData.width) / 2;
        values.ry = (values.height || layerData.height) / 2;
      }

      // 重新上传图片或者删除图片，需要重置裁剪以及位置信息
      if (
        (beType === LayerTypeBE.Image || beType === LayerTypeBE.Product) &&
        !isNil(values.src) &&
        values.src !== layerData.src
      ) {
        if (beType === LayerTypeBE.Image) {
          handleImageValuesChange(values, canvasWidth, canvasHeight);
        } else {
          // product image 上传后不做缩放，这点需要特殊处理
          handleProductImageValuesChange(values);
        }

        needUpdateForm = true;
      }

      // Text类型，data内数据更改，或者width height更改，需要重新real time preview请求图片
      if (beType === LayerTypeBE.Text && values.data) {
        values.data.needPreview = true;
      }
      if (beType === LayerTypeBE.Text && (values.width || values.height)) {
        values.data = { needPreview: true };
      }

      onChange(values, needUpdateForm, needRerenderScreen);
    },
    // eslint-disable-next-line react-hooks/exhaustive-deps
    [beType, layerData, onChange]
  );

  useEffect(() => {
    // 手动触发form更改
    const resetLayerForm = (layers: LayerInfoFE[]): void => {
      form.setFieldsValue(layers[index]);
    };
    emitter.on(EVENT_TYPE.resetLayerForm, resetLayerForm);
    return (): void => emitter.off(EVENT_TYPE.resetLayerForm, resetLayerForm);
  }, [form, index]);

  return (
    <Form
      form={form}
      initialValues={layerData}
      layout="vertical"
      onValuesChange={handleValuesChange}
      className={styles['layers-form']}
    >
      {hasShapes && (
        <ShapeConfigs data={layerData} onChange={handleValuesChange} />
      )}
      <BaseConfigs
        layer={layerData}
        hasCorner={hasCorner}
        disabled={
          ((hasImage || hasProductImage) && !layerData?.data?.image?.name) ||
          loading // 上传中禁用修改
        }
      />
      {hasImage && (
        <ImageConfigs
          layer={layerData}
          loading={loading}
          setLoading={setLoading}
          onChange={handleValuesChange}
          onSetCropLayerId={onSetCropLayerId}
        />
      )}
      {hasProductImage && (
        <ProductImageConfigs
          layer={layerData}
          loading={loading}
          setLoading={setLoading}
          onChange={handleValuesChange}
        />
      )}
      {hasText && (
        <TextConfigs layer={layerData} onChange={handleValuesChange} />
      )}
      {(hasBorderColor || hasFillColor) && (
        <ColorConfigs
          layer={layerData}
          hasBorder={hasBorderColor}
          hasFill={hasFillColor}
        />
      )}
    </Form>
  );
};

export default LayerConfigs;
